<?php

namespace App\Http\Controllers;

use App\Datas\ModelList;
use App\Datas\ModelStyle;
use App\Datas\Opus;
use App\Datas\Pay;
use App\Datas\User;
use App\Datas\UserStyle;
use App\Datas\DrawingBoardPrepare;
use App\Tools\FunTool;
use App\Tools\Translator;
use App\Tools\Sensitive;
use App\Tools\IPFactory;
use App\Tools\Task;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;

class ModelController extends Controller
{

    /**
     * 是否免费试用
     * @var bool
     */
    private $isFreeDrawing = false;

    /**
     * 模型首页
     * @param Request $request
     * @return array
     */
	public function index(Request $request) {
		$aDataList = ModelList::getInstance()->getIndexList();
		//未付费用户展示模型按照顺序走 2023-06-29
		$oPay = new Pay();
		$iUserID = $this->getTokenUser();
		$bPaid = $oPay->getDevicePaidByUserID($iUserID);
		//if('c6e6ef6defbe286898c4a834d0064656'==$sDeviceID){
		//	Log::info("index-rand",["bPaid" => $bPaid, 'Device_id'=>$sDeviceID]);
		//}
		if(true === $bPaid) {
			$aDataList = FunTool::shuffleLists($aDataList);
		}
		return $this->buildReturn(Code::SUCCESS, ["list" => $aDataList]);
	}

    /**
     * 模型首页--new
     * @param Request $request
     * @return array
     */
    public function new_index(Request $request) {
        $aDataList = ModelList::getInstance()->getNewIndexList();
        //未付费用户展示模型按照顺序走 2023-06-29
        $oPay = new Pay();
        $iUserID = $this->getTokenUser();
        $bPaid = $oPay->getDevicePaidByUserID($iUserID);
        //if('c6e6ef6defbe286898c4a834d0064656'==$sDeviceID){
        //  Log::info("index-rand",["bPaid" => $bPaid, 'Device_id'=>$sDeviceID]);
        //}
        if(true === $bPaid) {
            $aDataList = FunTool::shuffleLists($aDataList);
        }
        return $this->buildReturn(Code::SUCCESS, ["list" => $aDataList]);
    }

    public function all(Request $request) {
		$aDataList = ModelList::getInstance()->getAllList();
		//未付费用户展示模型按照顺序走 2023-06-29
		$oPay = new Pay();
		$iUserID = $this->getTokenUser();
		$bPaid = $oPay->getDevicePaidByUserID($iUserID);
		//if('c6e6ef6defbe286898c4a834d0064656'==$sDeviceID){
		//	Log::info("all-rand",["bPaid" => $bPaid, 'Device_id'=>$sDeviceID]);
		//}
		if(true === $bPaid) {
			$aDataList = FunTool::shuffleLists($aDataList);
		}
        return $this->buildReturn(Code::SUCCESS,["list" => $aDataList]);
    }
    /**
     * 新版接口
     */
    public function new_all(Request $request) {
        $aDataList = ModelList::getInstance()->getNewAllList();
        $oPay = new Pay();
        $iUserID = $this->getTokenUser();
        $bPaid = $oPay->getDevicePaidByUserID($iUserID);
        if(true === $bPaid) {
            $aDataList = FunTool::shuffleLists($aDataList);
        }
        return $this->buildReturn(Code::SUCCESS,["list" => $aDataList]);
    }

	/**
	 * 获取图生图列表
	 * @param Request $request
	 * @return array
	 */
    public function img2img(Request $request) {
		$aDataList = ModelList::getInstance()->getImg2ImgList();
		//未付费用户展示模型按照顺序走 2023-06-29
		$oPay = new Pay();
		$iUserID = $this->getTokenUser();
		$bPaid = $oPay->getDevicePaidByUserID($iUserID);
		//if('c6e6ef6defbe286898c4a834d0064656'==$sDeviceID){
		//	Log::info("img2img-rand",["bPaid" => $bPaid]);
		//}
		if(true === $bPaid) {
			$aDataList = FunTool::shuffleLists($aDataList);
		}
        return $this->buildReturn(Code::SUCCESS,["list" => $aDataList]);
    }

    public function style_list(Request $request) {
        $this->validate($request, [
            'model_id' => ['required'],
        ]);

        $model_id = intval($request->get("model_id",0));
        $page = intval($request->get('page',1));

        if ($model_id < 1) {
            return $this->buildReturn(Code::PARAM_ERROR);
        }

        $modelInfo = ModelList::getInstance()->getOneInfoById($model_id,["status","vip"]);
        if (empty($modelInfo) || $modelInfo["status"] != ModelList::STATUS_ANLE) {
            return $this->buildReturn(Code::MODEL_DISABLE);
        }

        $return = [
            "page" => 0,
            "list" => []
        ];

        $page = ($page < 1) ? 1 : $page;
        $limit = ($page - 1) * parent::PAGE_SIZE;

        $count = ModelStyle::getInstance()->getCountByModelId($model_id);
        $list = ModelStyle::getInstance()->select("id,img",["model_id" => $model_id],"ORDER BY sort DESC,id DESC",$limit,parent::PAGE_SIZE);
        $return["list"] = ModelStyle::getInstance()->formatList($list);

        //补充下vip的图标
        $vipIcon = $modelInfo["vip"] == ModelList::IS_VIP ? FunTool::getVipImg() : "";
        foreach ($return["list"] as &$item) {
            $item["vip"] = $vipIcon;
        }

        if ($count > $limit + parent::PAGE_SIZE) {
            $return["page"] = $page + 1;
        } else {
            $return["page"] = 0;
        }

        return $this->buildReturn(Code::SUCCESS,$return);
    }
    /**
     * 新版接口
     */
    public function new_style_list(Request $request) {
        $this->validate($request, [
            'model_id' => ['required'],
        ]);

        $model_id = intval($request->get("model_id",0));
        $page = intval($request->get('page',1));

        if ($model_id < 1) {
            return $this->buildReturn(Code::PARAM_ERROR);
        }

        $modelInfo = ModelList::getInstance()->getOneInfoById($model_id,["status","vip","is_life_vip_pro"]);
        if (empty($modelInfo) || $modelInfo["status"] != ModelList::STATUS_ANLE) {
            return $this->buildReturn(Code::MODEL_DISABLE);
        }

        $return = [
            "page" => 0,
            "list" => []
        ];

        $page = ($page < 1) ? 1 : $page;
        $limit = ($page - 1) * parent::PAGE_SIZE;

        $count = ModelStyle::getInstance()->getCountByModelId($model_id);
        $list = ModelStyle::getInstance()->select("id,img",["model_id" => $model_id],"ORDER BY sort DESC,id DESC",$limit,parent::PAGE_SIZE);
        $return["list"] = ModelStyle::getInstance()->formatList($list);

        //补充下vip的图标
        $vipIcon = $modelInfo["vip"] == ModelList::IS_VIP ? FunTool::getVipImg() : "";
        foreach ($return["list"] as &$item) {
            $item["vip"] = $vipIcon;
            $item["is_life_vip_pro"] = $modelInfo['is_life_vip_pro'];
        }

        if ($count > $limit + parent::PAGE_SIZE) {
            $return["page"] = $page + 1;
        } else {
            $return["page"] = 0;
        }

        return $this->buildReturn(Code::SUCCESS,$return);
    }

    public function style_detail(Request $request) {
        $this->validate($request, [
            'id' => ['required'],
        ]);

        $id = intval($request->get("id",0));

        if ($id <= 0) {
            return $this->buildReturn(Code::PARAM_ERROR);
        }

        $info = ModelStyle::getInstance()->getOneInfo([
            "id" => $id,
            "status" => ModelStyle::STATUS_ANLE
        ],['name','img','prompt','dot','status','model_id']);
        if (empty($info)) {
            return $this->buildReturn(Code::STYLE_DISABLE);
        }

        ModelStyle::getInstance()->formatItem($info);
        $info["share_img"] = $info["img"].FunTool::getShareImgMark();
        //补充VIP图标
        $info["vip"] = ModelList::getInstance()->getModelVipById($info["model_id"]) ? FunTool::getVipImg() : "";
        return $this->buildReturn(Code::SUCCESS,["info" => $info,"high_drawing_dot" => FunTool::getHighDrawingDot()]);
    }

	/**
	 * 获取图生图详情
	 * @param Request $request
	 * @return array
	 * @throws \Illuminate\Validation\ValidationException
	 */
    public function img2img_detail(Request $request) {
        $this->validate($request, [
            'id' => ['required'],
        ]);

        $id = intval($request->get("id",0));
        if ($id <= 0) {
            return $this->buildReturn(Code::PARAM_ERROR);
        }

        $modelInfo = ModelList::getInstance()->getOneInfo([
            "id" => $id,
            "status" => ModelList::STATUS_ANLE,
            "img2img" => ModelList::IMG2IMG,
        ],["id","name","video","video_img","video_webp","detail_video_img","height_v","width_v","hot","vip","status"]);
        if (empty($modelInfo)) {
            return $this->buildReturn(Code::MODEL_DISABLE);
        }
        ModelList::getInstance()->formatItem($modelInfo);

        return $this->buildReturn(Code::SUCCESS,["info" => $modelInfo]);
    }

    public function buy_style(Request $request) {
        $this->validate($request, [
            'id' => ['required'],
        ]);

        $userId = $this->getTokenUser() ?? 0;
        //$userId = 1;
        if ($userId < 1) {
            return $this->buildReturn(Code::NOT_LOGIN);
        }
        $userInfo = (new User())->getUser($userId);

        $id = intval($request->post("id",0));
        $styleInfo = ModelStyle::getInstance()->getOneInfoById($id,['status',"dot"]);
        if (empty($styleInfo) || $styleInfo["status"] != ModelStyle::STATUS_ANLE) {
            return $this->buildReturn(Code::STYLE_DISABLE);
        }

        $dot = $styleInfo["dot"];
        if ($dot > $userInfo["dot"]) {
            return $this->buildReturn(Code::LACK_DOT);
        }

        $info = UserStyle::getInstance()->getOneInfo(["user_id" => $userId,"style_id" => $id]);
        if (empty($info)) {
            DB::beginTransaction();
            (new User())->updateDot($userId, -$dot, 3);
            UserStyle::getInstance()->insert([
                'user_id' => $userId,
                "style_id" => $id,
                "dot" => $dot
            ]);
            DB::commit();
        }

        return $this->buildReturn(Code::SUCCESS);

    }

    /**
     * @param $style_id
     * @param $isModelVip
     * @return array|bool[]
     */
    private function checkEquityByTxt($style_id,$isModelVip = false) {
        $return = [];
        $userId = $this->getTokenUser() ?? 0;
        //$userId = 42984;
        $isNoVip = true;
        if ($userId > 0) {
            $userInfo = (new User())->getUser($userId);

            if ($userInfo["vip_exp"] > time()) {
                $isNoVip = false;
                $isBuyStyle = UserStyle::getInstance()->getOneInfo([
                    'user_id' => $userId,
                    "style_id" => $style_id,
                ],["id"]);
                if (empty($isBuyStyle)) {
                    $return = [
                        "buy_style_alert" => true,
                    ];
                }
            }
        }

        // 未登录和不是vip的，统一归为试用
        if ($isNoVip) {
            //默认的支付规则
            $ruleData = (new Pay())->getGuideRule();
            $this->isFreeDrawing = true;
            if ( $isModelVip == true) {
                $return = [
                    "model_vip_alert" => true,
                    'model_num' => ModelList::getInstance()->getAbleCount(),
                    "payRuleData" => $ruleData,
                ];
            } else {
                $device_id = $this->getDeviceId();
                if ($userId > 0) {
                    $freeNum = (new Opus())->getCountByWhere(["user_id" => $userId,"type" => 1]);
                }else{
                    $freeNum = (new Opus())->getCountByWhere(["device_id" => $device_id,"type" => 1]);
                }
                if ($freeNum >= FunTool::getFreeNum()) {
                    $return = [
                        "free_num_alert" => true,
                        'model_num' => ModelList::getInstance()->getAbleCount(),
                        "payRuleData" => $ruleData,
                    ];
                }
            }
        }

        return $return;
    }

    private function checkLifeVipProAlert($modelInfo, $userInfo){
        $alert = [
            'is_life_vip_pro_alert' => true,
            'model_num' => ModelList::getInstance()->getAbleCount(),
            'payRuleData' => (new Pay())->getGuideRule()
        ];

        return ['alert'=>$alert];
    }

    /**
     *
     * @param Request $request
     * @return array
     * @throws \Illuminate\Validation\ValidationException
     */
    public function prepare_txt(Request $request) {
        $this->validate($request, [
            'id' => ['required'],
        ]);
        $return = [];
        $id = intval($request->get("id",0));

        if ($id <= 0) {
            return $this->buildReturn(Code::PARAM_ERROR);
        }

        $userId = $this->getTokenUser() ?? 0;

        $info = ModelStyle::getInstance()->getOneInfo([
            "id" => $id,
            "status" => ModelStyle::STATUS_ANLE,
        ],['id','model_id']);
        if (empty($info)) {
            return $this->buildReturn(Code::STYLE_DISABLE);
        }

        $modelInfo = ModelList::getInstance()->getModelInfoById($info['model_id']);

        $userInfo = (new User())->getUser($userId);

        if (1 == $modelInfo['is_life_vip_pro'] && version_compare($this->getVersion(),"1.8.4") >= 0) {//终生会员模型弹窗逻辑
            if (empty($userInfo) || 0 == $userInfo['is_super_vip']) {
                $returnData =  $this->checkLifeVipProAlert($modelInfo, $userInfo);
                return $this->buildReturn(Code::SUCCESS,$returnData);
            }
        }
        
        $modelVip = ModelList::getInstance()->getModelVipById($info["model_id"]);

        $check = $this->checkEquityByTxt($id,$modelVip);

        if (!empty($check)) {
            $return["alert"] = $check;
        } else {
            $return = new \stdClass();
        }

        return $this->buildReturn(Code::SUCCESS,$return);
    }

	/**
	 * 文生图
	 * @param Request $request
	 * @return array
	 *
	 *  1 竖版, 3 横版, 2 正方形
	 */
    public function task_txt(Request $request){
        $this->validate($request, [
            'prompt' => ['required'],
            'resolution' => ['required', Rule::in([1, 2, 3])],
            'id' => ['required'],//描述词ID
        ]);

        $id = intval($request->get("id",0));//描述词ID

        if ($id <= 0) {
            return $this->buildReturn(Code::PARAM_ERROR);
        }

        $taskId = $this->getRoundToken();
        $userId = $this->getTokenUser() ?? 0;
        $deviceId = $this->getDeviceId() ?? '';

        if (!$userId) {
            return $this->buildReturn(Code::OPUS_NOT_LOGIN);
        }
        $repeat = (new Task())->checkAddTaskRepeat($deviceId, $userId);
        if ($repeat > 0) {
            return $this->buildReturn(Code::WAIT_TIME1);
        }

        $info = ModelStyle::getInstance()->getOneInfo([
            "id" => $id,
            "status" => ModelStyle::STATUS_ANLE,
        ],['id','model_id',"prompt","negative_prompt"]);
        if (empty($info)) {
            return $this->buildReturn(Code::STYLE_DISABLE);
        }

        $modelInfo = ModelList::getInstance()->getOneInfo([
            "id" => $info["model_id"],
        ],["vip","machine_id","model","number","negative_prompt"]);

        //权益的校验
        $modelVip = $modelInfo["vip"] == ModelList::IS_VIP ? true : false;
        $check = $this->checkEquityByTxt($id,$modelVip);
        if (!empty($check)) {
            return $this->buildReturn(Code::SUCCESS,["alert" => $check]);
        }

		$sPrompt = trim($request->post('prompt'));
		$sPrompt = empty($sPrompt) ? $info["prompt"] : $sPrompt;
		//用户没有修改过词条
		$isStyleOrginal = $sPrompt == $info["prompt"] ? 1 : 0;

        $resolution = $request->post('resolution',1);
        $isHigh = intval($request->post("is_high",0));
        list($width,$height) = FunTool::getHeightAndWidthByResolution($resolution);
        $noHighAmount = (new Opus())->getNoHighAmountByDay($userId, FunTool::getDeviceId());
        $amount = (new Opus())->getAmountByDay($userId, FunTool::getDeviceId());
        $nowVersion = FunTool::getVersion();
        $special = 0;
        if (version_compare($nowVersion,"1.8.4") >= 0 && $noHighAmount == 3 && $amount == 3) {//每天前3张非高清后，第四张高清不消耗点数
            $special = 1;
        }
        if (!$this->isFreeDrawing && $isHigh == 1 && $special==0) {
            $highDrawingDot = FunTool::getHighDrawingDot();
            $userObj = new User();
            $userInfo = $userObj->getUser($userId);
            if ($userInfo["dot"] < FunTool::getHighDrawingDot()) {
                return $this->buildReturn(Code::LACK_DOT);
            }
            $userObj->updateDot($userId,-$highDrawingDot,8);
        }

        $postData = [];
        $postData['model_id'] = $info["model_id"];
        $postData['model'] = $modelInfo['number'] ?? '';
        $postData['machine_id'] = $modelInfo['machine_id'];
        $postData['task_id'] = $taskId;
        $postData['user_id'] = $userId;
        $postData['type'] = 1;
        $postData['prompt'] = $sPrompt;
        $postData['negative_prompt'] = empty($info['negative_prompt']) ? $modelInfo['negative_prompt'] : $info['negative_prompt'];
        $postData['height'] = $height;
        $postData['width'] = $width;
        $postData['drawing_url'] = '';
        $postData['is_high'] = $isHigh;
        $postData['style_id'] = $id;
        $postData['is_style_orginal'] = $isStyleOrginal;
        $postData['platform'] = $this->getPlatform();
        $postData['prepare_id'] = 0;
        $postData['special'] = $special;
        $res = (new Task())->addTask($postData);

		//$res = $dataOpus->addNewPrint($info["model_id"], $modelInfo["model"], $modelInfo["machine_id"], $taskId, $userId, 1, $sPrompt, $translatorPrompt, $info["negative_prompt"], $height, $width, "", $isHigh, $id, $isStyleOrginal, $sPlatform, $special);
        return $this->buildReturn(Code::SUCCESS,["info" => $res]);
    }

	/**
	 * 图生图
	 * @param Request $request
	 * @return array
	 */
    public function task_img(Request $request) {
        $this->validate($request, [
            'id' => ['required'],
            'img' => ["required"],
            'resolution' => ['required', Rule::in([1, 2, 3])],
        ]);

        $id = intval($request->post("id",0));
        $img = trim($request->post("img",""));
        if ($id <= 0 || empty($img)) {
            return $this->buildReturn(Code::PARAM_ERROR);
        }

        $userId = $this->getTokenUser() ?? 0;
        $deviceId = $this->getDeviceId() ?? '';

        if (!$userId) {
            return $this->buildReturn(Code::OPUS_NOT_LOGIN);
        }

        $repeat = (new Task())->checkAddTaskRepeat($deviceId, $userId);
        if ($repeat > 0) {
            return $this->buildReturn(Code::WAIT_TIME1);
        }

        $modelInfo = ModelList::getInstance()->getOneInfo([
            "id" => $id,
            "status" => ModelList::STATUS_ANLE,
            "img2img" => ModelList::IMG2IMG,
        ]);
        if (empty($modelInfo)) {
            return $this->buildReturn(Code::MODEL_DISABLE);
        }

        $taskId = $this->getRoundToken();
        $resolution = intval($request->post('resolution',1));
        list($width,$height) = FunTool::getImg2ImgHeightAndWidthByResolution($resolution);

        $isNoVip = true;

        if ($userId > 0) {
            $userInfo = (new User())->getUser($userId);

            if ($userInfo["vip_exp"] > time()) {
                $isNoVip = false;
            }
        }

        if ($isNoVip) {
            //默认的支付规则
            $ruleData = (new Pay())->getGuideRule();
            $alert = [];
            if ( $modelInfo["vip"] == ModelList::IS_VIP) {
                $alert = [
                    "model_vip_alert" => true,
                    'model_num' => ModelList::getInstance()->getAbleCount(),
                    "payRuleData" => $ruleData,
                ];

            } else {
                $this->isFreeDrawing = true;
                if ($userId > 0) {
                    $freeNum = (new Opus())->getCountByWhere(["user_id" => $userId,"type" => 3]);
                }else{
                    $freeNum = (new Opus())->getCountByWhere(["device_id" => $deviceId,"type" => 3]);
                }
                if ($freeNum >= FunTool::getFreeNum()) {
                    $alert = [
                        "free_num_alert" => true,
                        'model_num' => ModelList::getInstance()->getAbleCount(),
                        "payRuleData" => $ruleData,
                    ];
                }
            }
            if (!empty($alert)) {
                return $this->buildReturn(Code::SUCCESS,["alert" => $alert]);
            }
        }

		$sPlatform = $this->getPlatform();
        $postData = [];
        $postData['model_id'] = $id;
        $postData['model'] = $modelInfo['number'];
        $postData['machine_id'] = $modelInfo['machine_id'];
        $postData['task_id'] = $taskId;
        $postData['user_id'] = $userId;
        $postData['type'] = 3;
        $postData['prompt'] = '';
        $postData['negative_prompt'] = $modelInfo['negative_prompt'];
        $postData['height'] = $height;
        $postData['width'] = $width;
        $postData['drawing_url'] = $img;
        $postData['is_high'] = 0;
        $postData['style_id'] = 0;
        $postData['is_style_orginal'] = 0;
        $postData['platform'] = $sPlatform;
        $postData['prepare_id'] = 0;
        $res = (new Task())->addTask($postData);
        // $res = $dataOpus->addNewPrint(
        //     $id,
        //     $modelInfo["model"],
        //     $modelInfo["machine_id"],
        //     $taskId,
        //     $userId,
        //     3,
        //     "",
        //     "",
        //     $modelInfo["negative_prompt"],
        //     $height,
        //     $width,
        //     $img,
		// 	0,0,0,$sPlatform
        // );
        return $this->buildReturn(Code::SUCCESS,["info" => $res]);
    }


	/**
	 * 指定模型 文生图
	 * @param Request $request
	 * @return array
	 *
	 *  1 竖版, 2 横版, 3 正方形
	 */
	public function task_model(Request $request) {
		$this->validate($request, [
			'prompt' => ['required'],
			'resolution' => ['required', Rule::in([1, 2, 3, 4])],
			'id' => ['required'],//模型ID
		]);

		$iModelID = intval($request->get('id', 0));//描述词ID

		if($iModelID <= 0) {
			return $this->buildReturn(Code::PARAM_ERROR);
		}

        $taskId = $this->getRoundToken();
        $userId = $this->getTokenUser() ?? 0;
        $deviceId = $this->getDeviceId() ?? '';

        if (!$userId) {
            return $this->buildReturn(Code::OPUS_NOT_LOGIN);
        }

		$modelInfo = ModelList::getInstance()->getOneInfo([
			'id' => $iModelID,
		], ['vip', 'machine_id', 'model','negative_prompt','is_life_vip_pro','number']);

        $repeat = (new Task())->checkAddTaskRepeat($deviceId, $userId);
        if ($repeat > 0) {
            return $this->buildReturn(Code::WAIT_TIME1);
        }
		$sPrompt = trim($request->post('prompt'));
        $prepareId = trim($request->post('prepare_id', 0));
		$iResolution = $request->post('resolution', 1);//图片形状
		$isHigh = intval($request->post('is_high', 0));//是否高清
        $isVideo = intval($request->post('is_video', 0));//是否生成视频

		list($width, $height) = FunTool::getHeightAndWidthByResolution($iResolution);//返回图片的宽高
        $userInfo = (new User())->getUser($userId);

        if ($prepareId > 0) {//预制词信息
            $prepareInfo = DrawingBoardPrepare::getFirst($prepareId);
            if ($prepareInfo['describition'] == $sPrompt) {
                $sPrompt = $prepareInfo['prompt'];
            }
            if (empty($modelInfo['negative_prompt'])) {
                $modelInfo['negative_prompt'] = $prepareInfo['negative_prompt'];
            }
        }
        if (1 == $modelInfo['is_life_vip_pro'] && version_compare($this->getVersion(),"1.8.4") >= 0 ) {//终生会员模型弹窗逻辑
            if (empty($userInfo) || 0 == $userInfo['is_super_vip']) {
                $returnData =  $this->checkLifeVipProAlert($modelInfo, $userInfo);
                return $this->buildReturn(Code::SUCCESS,$returnData);
            }
        }

        $isNoVip = true;
        if ($userId > 0) {
            $userInfo = (new User())->getUser($userId);

            if ($userInfo["vip_exp"] > time()) {
                $isNoVip = false;
            }
        }

        if ($isNoVip) {
            //默认的支付规则
            $ruleData = (new Pay())->getGuideRule();

            $alert = [];
            if ( $modelInfo["vip"] == ModelList::IS_VIP) {
                $alert = [
                    "model_vip_alert" => true,
                    'model_num' => ModelList::getInstance()->getAbleCount(),
                    "payRuleData" => $ruleData,
                ];

            } else {
                $this->isFreeDrawing = true;
                if ($userId > 0) {
                    $freeNum = (new Opus())->getCountByWhere(["user_id" => $userId,"type" => 1]);
                }else{
                    $freeNum = (new Opus())->getCountByWhere(["device_id" => $deviceId,"type" => 1]);
                }
                if ($freeNum >= FunTool::getFreeNum()) {
                    $alert = [
                        "free_num_alert" => true,
                        'model_num' => ModelList::getInstance()->getAbleCount(),
                        "payRuleData" => $ruleData,
                    ];
                }
            }

            if (!empty($alert)) {
                return $this->buildReturn(Code::SUCCESS,["alert" => $alert]);
            }
        }

        $noHighAmount = (new Opus())->getNoHighAmountByDay($userId, FunTool::getDeviceId());
        $amount = (new Opus())->getAmountByDay($userId, FunTool::getDeviceId());
        $nowVersion = FunTool::getVersion();
        $special = 0;
        if (version_compare($nowVersion,"1.8.4") >= 0 && $noHighAmount == 3 && $amount == 3) {//每天前3张非高清后，第四张高清不消耗点数
            $special = 1;
        }
		if(!$this->isFreeDrawing && $isHigh == 1 && $special == 0 && $isVideo == 0) {
			$highDrawingDot = FunTool::getHighDrawingDot();
			$userObj = new User();
			$userInfo = $userObj->getUser($userId);
			if($userInfo['dot'] < FunTool::getHighDrawingDot()) {
				return $this->buildReturn(Code::LACK_DOT);
			}
			$userObj->updateDot($userId, -$highDrawingDot, 8);
		}

        if($isVideo == 1) {
            $highDrawingDot = FunTool::getImageVideoDot();
            $userObj = new User();
            $userInfo = $userObj->getUser($userId);
            if($userInfo['dot'] < FunTool::getImageVideoDot()) {
                return $this->buildReturn(Code::LACK_DOT);
            }
            $userObj->updateDot($userId, -$highDrawingDot, 8);
        }

        $postData = [];
        $postData['model_id'] = $iModelID;
        $postData['model'] = $modelInfo['number'];
        $postData['machine_id'] = $modelInfo['machine_id'];
        $postData['task_id'] = $taskId;
        $postData['user_id'] = $userId;
        $postData['type'] = 1;
        $postData['prompt'] = $sPrompt;
        $postData['negative_prompt'] = $modelInfo['negative_prompt'];
        $postData['height'] = $height;
        $postData['width'] = $width;
        $postData['drawing_url'] = '';
        $postData['is_high'] = $isHigh;
        $postData['is_video'] = $isVideo;
        
        $postData['style_id'] = 0;
        $postData['is_style_orginal'] = 0;
        $postData['platform'] = $this->getPlatform();
        $postData['prepare_id'] = $prepareId;
        $postData['special'] = $special;
        $res = (new Task())->addTask($postData);

		//$res = $dataOpus->addNewPrint($iModelID, $modelInfo['model'], $modelInfo['machine_id'], $taskId, $userId, 1, $sPrompt, $translatorPrompt, $modelInfo['negative_prompt'], $height, $width, '', $isHigh, 0, 0, $sPlatform, $special);
		return $this->buildReturn(Code::SUCCESS, ['info' => $res]);
	}


    /**
     * 指定模型 文生视频
     * @param Request $request
     * @return array
     */
    public function task_txt_video(Request $request) {
        $this->validate($request, [
            'prompt' => ['required'],
            // 'resolution' => ['required', Rule::in([1, 2, 3])],
            'id' => ['required'],//模型ID
        ]);

        $iModelID = intval($request->get('id', 0));//描述词ID

        if($iModelID <= 0) {
            return $this->buildReturn(Code::PARAM_ERROR);
        }

        $taskId = $this->getRoundToken();
        $userId = $this->getTokenUser() ?? 0;
        $deviceId = $this->getDeviceId() ?? '';

        if (!$userId) {
            return $this->buildReturn(Code::OPUS_NOT_LOGIN);
        }

        $modelInfo = ModelList::getInstance()->getOneInfo([
            'id' => $iModelID,
        ], ['vip', 'machine_id', 'model','negative_prompt','is_life_vip_pro','number']);

        $repeat = (new Task())->checkAddTaskRepeat($deviceId, $userId);
        if ($repeat > 0) {
            return $this->buildReturn(Code::WAIT_TIME1);
        }
        $sPrompt = trim($request->post('prompt'));
        $prepareId = trim($request->post('prepare_id', 0));
        $iResolution = $request->post('resolution', 1);//图片形状
        $isHigh = intval($request->post('is_high', 0));//是否高清

        // list($width, $height) = FunTool::getHeightAndWidthByResolution($iResolution);//返回图片的宽高
        $width = 0;
        $height = 0;

        $userInfo = (new User())->getUser($userId);

        if ($prepareId > 0) {//预制词信息
            $prepareInfo = DrawingBoardPrepare::getFirst($prepareId);
            if ($prepareInfo['describition'] == $sPrompt) {
                $sPrompt = $prepareInfo['prompt'];
            }
            if (empty($modelInfo['negative_prompt'])) {
                $modelInfo['negative_prompt'] = $prepareInfo['negative_prompt'];
            }
        }
        if (1 == $modelInfo['is_life_vip_pro'] && version_compare($this->getVersion(),"1.8.4") >= 0 ) {//终生会员模型弹窗逻辑
            if (empty($userInfo) || 0 == $userInfo['is_super_vip']) {
                $returnData =  $this->checkLifeVipProAlert($modelInfo, $userInfo);
                return $this->buildReturn(Code::SUCCESS,$returnData);
            }
        }

        $isNoVip = true;
        if ($userId > 0) {
            $userInfo = (new User())->getUser($userId);

            if ($userInfo["vip_exp"] > time()) {
                $isNoVip = false;
            }
        }

        if ($isNoVip) {
            //默认的支付规则
            $ruleData = (new Pay())->getGuideRule();

            $alert = [];
            if ( $modelInfo["vip"] == ModelList::IS_VIP) {
                $alert = [
                    "model_vip_alert" => true,
                    'model_num' => ModelList::getInstance()->getAbleCount(),
                    "payRuleData" => $ruleData,
                ];

            } else {
                $this->isFreeDrawing = true;
                if ($userId > 0) {
                    $freeNum = (new Opus())->getCountByWhere(["user_id" => $userId, "type" => 4]);
                }else{
                    $freeNum = (new Opus())->getCountByWhere(["device_id" => $deviceId, "type" => 4]);
                }
                if ($freeNum >= FunTool::getFreeNum()) {
                    $alert = [
                        "free_num_alert" => true,
                        'model_num' => ModelList::getInstance()->getAbleCount(),
                        "payRuleData" => $ruleData,
                    ];
                }
            }

            if (!empty($alert)) {
                return $this->buildReturn(Code::SUCCESS,["alert" => $alert]);
            }
        }

        $noHighAmount = (new Opus())->getNoHighAmountByDay($userId, FunTool::getDeviceId());
        $amount = (new Opus())->getAmountByDay($userId, FunTool::getDeviceId());
        $nowVersion = FunTool::getVersion();
        $special = 0;
        // if (version_compare($nowVersion,"1.8.4") >= 0 && $noHighAmount == 3 && $amount == 3) {//每天前3张非高清后，第四张高清不消耗点数
        //     $special = 1;
        // }
        if(!$this->isFreeDrawing && $isHigh == 1 && $special == 0) {
            $highDrawingDot = FunTool::getHighDrawingDot();
            $userObj = new User();
            $userInfo = $userObj->getUser($userId);
            if($userInfo['dot'] < FunTool::getHighDrawingDot()) {
                return $this->buildReturn(Code::LACK_DOT);
            }
            $userObj->updateDot($userId, -$highDrawingDot, 8);
        }

        $postData = [];
        $postData['model_id'] = $iModelID;
        $postData['model'] = $modelInfo['number'];
        $postData['machine_id'] = $modelInfo['machine_id'];
        $postData['task_id'] = $taskId;
        $postData['user_id'] = $userId;
        $postData['type'] = 4;
        $postData['prompt'] = $sPrompt; //$sPrompt;
        $postData['negative_prompt'] = $modelInfo['negative_prompt'];
        $postData['height'] = $height;
        $postData['width'] = $width;
        $postData['drawing_url'] = '';
        $postData['is_high'] = $isHigh;
        $postData['style_id'] = 0;
        $postData['is_style_orginal'] = 0;
        $postData['platform'] = $this->getPlatform();
        $postData['prepare_id'] = $prepareId;
        $postData['special'] = $special;

        // motion 抖动（1-4）
        // prompt 提示词（已有）
        // proportion 视频比例16:9
        // videoDuration 视频时长
        // videoQuantity 视频质量
        $postData['motion'] = 1;
        $postData['proportion'] = '16:9';
        $postData['videoDuration'] = 3;
        $postData['videoQuantity'] = 1;

        $res = (new Task())->addTask($postData);
        return $this->buildReturn(Code::SUCCESS, ['info' => $res]);
    }


	//@todo 同 OpusController
	//敏感词替换 start
	public function handleSensitiveWord($sPrompt, $sReplacement = '***') {

        $string = Sensitive::formatData($sPrompt, $sReplacement, $this->getTokenUser(), $this->getPlatform());

        return $string;

	}

	private function _replaceSensitiveWord($sString, $aSensitiveWord, $sReplacement = '***') {
		$bIsEn = $this->_isEn($sString);
		if(!empty($aSensitiveWord)) {
			foreach($aSensitiveWord as $sSensitiveWord) {
				if(true === $bIsEn) {
					if(strtolower($sString) == $sSensitiveWord) {
						return $sReplacement;
					}
				} else {
					$sString = str_ireplace($sSensitiveWord, $sReplacement, $sString);
				}
			}
		}
		return $sString;
	}

	private function _isEn($sKeyword) {
		$Res = preg_match('/^[A-Za-z0-9]+$/', $sKeyword);
		if($Res) {
			return true;
		} else {
			return false;
		}
	}
	//敏感词替换 end
}